from django.http import JsonResponse
from django.views import View
from django.shortcuts import HttpResponse
from django.contrib.contenttypes.models import ContentType

from rest_framework.views import  APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import APIException
from rest_framework.authentication import BaseAuthentication
from rest_framework.renderers import JSONRenderer

from serializer.app_serializer import BookSerializer
from .models import (
    Book,
    User,
    UserToken
)
from .models import (
    PythonBasic,
    Coupon,
    Oop,
)

from serializer.utils import get_token
from .utils.app_throttles import RateThrottle
from .utils.app_paginates import MyPagination

"""
class BookView(APIView):
    def get(self,request):
        # 第三步，获取queryset
        origin_data = Book.objects.all()

        # 第四步，开始序列化
        serialized_data = BookSerializer(origin_data, many=True)    # many=True 是传入多行数据

        return Response(serialized_data.data)

    def post(self,request):

        verified_data = BookSerializer(data=request.data)
        if verified_data.is_valid():    # 校验数据
            book = verified_data.save()
            authors = Author.objects.filter(nid__in=request.data["authors"])
            book.authors.add(*authors)
            print("verified_data:-----",verified_data.data)
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)


class BookFilter(APIView):
    # 获取单挑数据
    def get(self, request, id):
        book_obj = Book.objects.get(pk=id)

        serialized_data = BookSerializer(book_obj, many=False)
        return Response(serialized_data.data)

    # 修改
    def put(self, request, id):
        book_obj = Book.objects.get(pk=id)
        verified_data = BookSerializer(data=request.data, instance=book_obj, many=False)
        if verified_data.is_valid():
            verified_data.save()
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)


    def delete(self, request, id):
        book_obj = Book.objects.get(pk=id).delete()
        return Response()
"""


# 优化
"""
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self,request):
        return self.list(request)

    def post(self,request):
        return self.create(request)


class BookFilter(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
"""


# 再优化
"""
class BookView(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer



class BookFilter(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
"""


# 再再优化 viewset


# 第一步：定义认证类
class UserAuth(BaseAuthentication):

    # 第三步：所有的认证逻辑都在authenticate
    def authenticate(self,request):
        user_token = request.query_params.get("token")  # query_params == GET
        try:
            token = UserToken.objects.get(token=user_token)
            print(token)
            # 后面权限会用到
            # 返回验证后的user和token
            return token.user, token.token
        except Exception:
            raise APIException("没有认证")

# 定义权限类
class UserPerm():
    message = "你没有查看该数据的权限!"
    def has_permission(self,request,view):
        if request.user.user_type == 3 or 2:
            return True
        return None

"""
# 使用DRF自带的分页器
class BookView(APIView):
    def get(self,request):
        books = Book.objects.all()
        paginater = PageNumberPagination()
        paged_books = paginater.paginate_queryset(books, request)
        serialized_books = BookSerializer(paged_books, many=True)

        return JsonResponse(serialized_books.data,safe=False)
"""


class BookView(APIView):
    def get(self,request):
        books = Book.objects.all()
        paginator = MyPagination()
        paged_books = paginator.paginate_queryset(books, request)
        serialized_books = BookSerializer(paged_books, many=True)
        return JsonResponse(serialized_books.data, safe=False)


class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

"""
class BookView(ModelViewSet):
    #第二步：指定认证类
    # UserAuth在全局可以找到，所以就不需要再写
    # authentication_classes = [UserAuth]
    # permission_classes = [UserPerm]
    throttle_classes = [RateThrottle]
    renderer_classes = [JSONRenderer]
    pagination_class = [MyPagination]

    queryset = Book.objects.all()
    serializer_class = BookSerializer
"""

class UserView(APIView):
    def post(self,request):
        # 定义返回消息体
        response = dict()
        # 定义需要的用户信息
        fields = {"username","password"}
        # 定义一个用户信息字典
        user_info = dict()
        if fields.issubset(set(request.data.keys())):
            # username = request.data.get("username")
            # password = request.data.get("password")
            for key in fields:
                user_info[key] = request.data[key]

            user_instance = User.objects.filter(**user_info).first()

            if user_instance is not None:
                access_token = get_token.generate_token()
                UserToken.objects.update_or_create(user=user_instance,defaults={
                    'token':access_token
                })

                response["status_code"] = 200
                response["status_message"] = "登录成功"
                response["access_token"] = access_token
                response["user_role"] = user_instance.get_user_type_display()
            else:
                response["status_code"] = 201
                response["status_message"] = "登录失败，用户名或密码错误"

            return JsonResponse(response)

class CourseView(View):
    def get(self,request):
        # 获取表名
        # pb = ContentType.objects.filter(app_label="serializer", model="pythonbasic").first()
        # pb_model = pb.model_class()
        # print(pb_model.objects.all())

        object_id = PythonBasic.objects.get(id=3)
        Coupon.objects.create(coupon_name="Python基础通关优惠券", content_obj=object_id)
        return HttpResponse("Ok")










